package top.mccat.filesystem.controller;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import top.mccat.filesystem.anno.CurrentAccount;
import top.mccat.filesystem.anno.UserLoginToken;
import top.mccat.filesystem.bean.Account;
import top.mccat.filesystem.bean.MyFile;
import top.mccat.filesystem.factory.CookieFactory;
import top.mccat.filesystem.factory.TokenFactory;
import top.mccat.filesystem.service.AccountService;
import top.mccat.filesystem.utils.checker.AccountCheckUtils;
import top.mccat.filesystem.utils.AjaxResult;
import top.mccat.filesystem.utils.checker.StringUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author JMY
 */
@RestController
@RequestMapping("/account")
@Slf4j
public class AccountController {
    @Autowired
    private AccountService accountService;

    @Value("${pageSize}")
    private Integer pageSize;
    /**
     * 登录
     * @param account
     * @param response
     * @return
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody Account account, HttpServletResponse response){
        String name = account.getUserName();
        //用户名验证
        if(StringUtils.isBlank(name)){
            return AjaxResult.errorResult("登陆失败，用户名不能为为空！");
        }
        if(!AccountCheckUtils.nameChecker(name)){
            return AjaxResult.errorResult("登陆失败，用户名需为5-10位，只能为纯数字，不允许0开头！");
        }
        String pwd = account.getPassWord();
        //密码验证
        if(StringUtils.isBlank(pwd)){
            return AjaxResult.errorResult("登陆失败，密码不能为为空！");
        }
        if(!AccountCheckUtils.passwordChecker(pwd)){
            return AjaxResult.errorResult("登陆失败，密码需为字母开头，最短为8位，最大为16位！");
        }
        //进行mysql验证
        Account login = accountService.login(account);
        if(login==null){
            return AjaxResult.errorResult("登录失败，用户不存在或账户密码错误！");
        }
        log.debug("账户验证完成，用户名:{}，密码:{}，确认密码:{}，是否token登录:{}",name,pwd,account.getConfirmPassword(),account.isAutoLogin());
        String token = TokenFactory.getToken(login);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("user",account);
        Cookie cookie;
        Cookie admin;
        //生成令牌
        if(account.isAutoLogin()){
            cookie = CookieFactory.setCookie("token",token,60*60*24);
            admin = CookieFactory.setCookie("admin", ""+login.getIsAdmin(),60*60*24);
        }else {
            //设置半小时生命
            cookie = CookieFactory.setCookie("token",token,60*30);
            admin = CookieFactory.setCookie("admin", ""+login.getIsAdmin(),60*60*24);
        }
        log.debug("admin cookie:{}",admin.getValue());
        response.addCookie(cookie);
        response.addCookie(admin);
        return AjaxResult.successResult("登陆成功！",jsonObject);
    }

    /**
     * 注册
     * @param account
     * @return
     */
    @PostMapping("/register")
    public AjaxResult register(@RequestBody Account account){
        String name = account.getUserName();
        //用户名验证
        if(StringUtils.isBlank(name)){
            return AjaxResult.errorResult("注册失败，用户名不能为为空！");
        }
        if(!AccountCheckUtils.nameChecker(name)){
            return AjaxResult.errorResult("注册失败，用户名需为5-10位，只能为纯数字，不允许0开头！");
        }
        String pwd = account.getPassWord();
        //密码验证
        if(StringUtils.isBlank(pwd)){
            return AjaxResult.errorResult("注册失败，密码不能为为空！");
        }
        if(!AccountCheckUtils.passwordChecker(pwd)){
            return AjaxResult.errorResult("注册失败，密码需为字母开头，最短为8位，最大为16位！");
        }
        if(!pwd.equals(account.getConfirmPassword())){
            return AjaxResult.errorResult("注册失败，密码和确认密码并不相同！");
        }
        log.debug("账户格式验证完成，用户名:{}，密码:{}",name,pwd);
        //进行mysql验证,传递令牌，然后执行登录操作并返回令牌
        boolean register = accountService.register(account);
        if(!register){
            return AjaxResult.errorResult("注册失败，用户已存在！请更换一个用户名");
        }
        return AjaxResult.successResult("登陆成功！",null);
    }

    @UserLoginToken
    @GetMapping("/list")
    public AjaxResult listAccounts(@CurrentAccount Account account, Account myAccount, @RequestParam(defaultValue = "1",value = "pageNum") Integer pageNum){
        log.debug("account:{}",account);
        Account login = accountService.login(account);
        if(!login.getIsAdmin()){
            return AjaxResult.errorResult("当前账户并非管理员，无权进行账户管理操作！");
        }
        PageHelper.startPage(pageNum,pageSize);
        PageInfo<Account> accountPageInfo = new PageInfo<>(accountService.listAccounts(myAccount));
        return AjaxResult.successResult("查询成功！", accountPageInfo);
    }

    /**
     * token登录验证
     * @return 是否登录成功
     */
    @UserLoginToken
    @PostMapping("/edit")
    public AjaxResult updateUser(@CurrentAccount Account current, @RequestBody Account account, HttpServletResponse response){
        //查询账户查看管理员权限
        Account login = accountService.login(current);
        if(!login.getIsAdmin()) {
            return AjaxResult.errorResult("错误，用户并非管理员，请确定用户是否有管理员权限");
        }
        if(!AccountCheckUtils.passwordChecker(account.getPassWord())){
            return AjaxResult.errorResult("修改失败，密码应当以字母开头，8-15位！");
        }
        //如果当前账户为管理员，并且修改为非管理员需要更新cookie
        if(account.getUserName().equals(current.getUserName())){
            //如果管理员更改了当前账户的管理员状态，进行跳转component
            if(!account.getIsAdmin() && current.getIsAdmin()){
                response.addCookie(CookieFactory.setCookie("admin",""+account.getIsAdmin(), 60 * 30));
            }
            //如果当前用户进行了密码修改，直接将其踢出让其重新登录
            else if(login.getPassWord() != account.getPassWord()){
                response.addCookie(CookieFactory.setCookie("token","false", 60 * 30));
            }
        }
        boolean b = accountService.updateAccount(account);
        return AjaxResult.successResult("更新用户["+login.getUserName()+"]成功！",b);
    }

    @UserLoginToken
    @PostMapping("/delete")
    public AjaxResult deleteAccount(@CurrentAccount Account current, @RequestBody Account account){
        Account login = accountService.login(current);
        if(!login.getIsAdmin()) {
            return AjaxResult.errorResult("错误，用户并非管理员，请确定用户是否有管理员权限");
        }
        boolean b = accountService.deleteAccount(account);
        //如果当前账户为管理员，并且修改为非管理员需要更新cookie
        if(account.getUserName().equals(current.getUserName())){
            return AjaxResult.errorResult("您的账户已被删除，请重新登录", current);
        }
        return AjaxResult.successResult("删除用户["+login.getUserName()+"]成功！",b);
    }

    /**
     * token登录验证
     * @return 是否登录成功
     */
    @UserLoginToken
    @GetMapping("/login")
    public AjaxResult getMessage(){
        return AjaxResult.successResult("你已通过登录验证！");
    }
}
